package main

import (
	"log"
	"os"
	"path/filepath"
	"strings"
)

func createMap() map[string][]string {

	m := make(map[string][]string)
	m["create"] = []string{
		"Factory",
		"Singleton",
		"Builder",
		"Prototype",
	}
	m["structx"] = []string{
		"Adapter",
		"Bridge",
		"Filter",
		"Composite",
		"Decorator",
		"Facade",
		"Flyweight",
		"Proxy",
	}
	m["behavior"] = []string{
		"Chain",
		"Command",
		"Interpreter",
		"Iterator",
		"Mediator",
		"Memento",
		"Observer",
		"State",
		"Null",
		"Strategy",
		"Template",
		"Visitor",
	}
	return m
}

func create(root string, m map[string][]string) {
	for k, s := range m {
		for _, s2 := range s {
			os.MkdirAll(filepath.Join(root, strings.ToLower(k), strings.ToLower(s2)), 0777)
			os.Create(filepath.Join(root, strings.ToLower(k), strings.ToLower(s2)))
		}
	}
}

func main() {
	m := createMap()
	strings := []Project{
		{
			Typex:   "go",
			RootDir: "/home/debi/IdeaProjects/CodeDesign/go/design",
			Ext:     ".go",
			Handel: func(dir, fileName string) error {
				log.Println(dir, fileName)
				ext := filepath.Ext(fileName)
				os.WriteFile(filepath.Join(dir, fileName)+"_test.go", []byte("package "+strings.TrimRight(fileName, ext)), 0777)
				return nil
			},
		}, {
			Typex:   "rust",
			RootDir: "/home/debi/IdeaProjects/CodeDesign/rust/design/src/",
			Ext:     ".rs",
			Handel: func(dir string, fileName string) error {
				os.WriteFile(filepath.Join(dir, fileName)+".rs", []byte(""), 0777)
				return nil
			},
		},
	}
	for _, s := range strings {
		Run(s, m)
	}
}

type Project struct {
	Typex   string `json:"typex"`
	RootDir string `json:"root_dir"`
	Ext     string `json:"ext"`
	Handel  func(dir string, fileName string) error
}

func Run(p Project, moduls map[string][]string) error {
	for rootDir, models := range moduls {
		for _, item := range models {
			dir := filepath.Join(p.RootDir, strings.ToLower(rootDir), strings.ToLower(item))
			err := os.MkdirAll(dir, 0777)
			if err != nil {
				return err
			}
			switch strings.ToLower(p.Typex) {
			case "rust":
				p.Handel(dir, strings.ToLower(item))
			case "go":
				p.Handel(dir, strings.ToLower(item))
			case "kotlin":
				p.Handel(dir, strings.ToLower(item))
			}
		}
	}
	return nil
}
